package com.ikkong.biz.service.impl;

import com.google.common.collect.*;
import com.ikkong.biz.BizCst;
import com.ikkong.biz.excel.ClassesOfMode;
import com.ikkong.biz.service.TeacherService;
import com.ikkong.core.aop.AopContext;
import com.ikkong.core.constant.ConstCache;
import com.ikkong.core.dao.Db;
import com.ikkong.core.jfinal.ext.kit.JStrKit;
import com.ikkong.core.jfinal.ext.kit.JsonKit;
import com.ikkong.core.jfinal.ext.shiro.ShiroKit;
import com.ikkong.core.toolbox.Conver;
import com.ikkong.core.toolbox.ExcelStatistic;
import com.ikkong.core.base.service.impl.BaseService;
import com.ikkong.biz.model.Classes;
import com.ikkong.biz.model.Parent;
import com.ikkong.biz.model.Student;
import com.ikkong.biz.service.ClassesService;
import com.ikkong.core.dao.Blade;
import com.ikkong.core.exception.BizException;
import com.ikkong.core.jfinal.ext.kit.JLogKit;
import com.ikkong.core.toolbox.Func;
import com.ikkong.core.toolbox.Record;
import com.ikkong.core.toolbox.kit.DateKit;
import com.ikkong.system.model.Dept;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.plugin.ehcache.IDataLoader;
import com.jfinal.upload.UploadFile;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.SQLReady;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.result.ExcelImportResult;
import org.jeecgframework.poi.exception.excel.ExcelImportException;
import org.jeecgframework.poi.util.PoiPublicUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.util.*;

import static com.ikkong.common.config.MainConfig.map;

/**
 * Generated by Blade.
 * 2016-11-13 16:56:20
 */
public class ClassesServiceImpl extends BaseService<Classes> implements ClassesService{
    private static final String filePath = "excel"+ File.separator+"classes"+File.separator+"classes_import.xlsx";
    private TeacherService service = new TeacherServiceImpl();


    @Override
    public String doImport(File file) throws BizException{
        FileOutputStream fos = null;
        try {
        	

            ImportParams params = new ImportParams();
            params.setNeedVerfiy(true);
            ExcelImportResult<ClassesOfMode> result = ExcelImportUtil.importExcelVerify(
                    file,
                    ClassesOfMode.class, params);
            String realpath = PathKit.getWebRootPath()+File.separator+ filePath;
            fos = new FileOutputStream(realpath);
            result.getWorkbook().write(fos);
            fos.close();

            int count = 1;
            Integer max = Db.init().queryInt("select max(id) from tfw_dept", null);
            if (null != max){
                count +=max.intValue();
            }

            List<Classes> clss = Lists.newArrayList();
            List<Dept> depts = Lists.newArrayList();
            for (ClassesOfMode cm:result.getList()) {
                if (StrKit.isBlank(cm.getErrorMsg())){
                    cm.setVersion(0);
                    cm.setIs_graduate(1);
                    cm.setCtime(new Date());
                    cm.setStu_dept_id(count);
                    String fullclass = Func.getDictName(1001,cm.getGrade_id()) + cm.getClass_name();

                    //处理学生部门
                    Dept stuDept = new Dept();
                    stuDept.setId(count);
                    stuDept.setType(BizCst.STU_TYPE);
                    stuDept.setSimplename(fullclass);
                    stuDept.setFullname(fullclass+"学生");
                    stuDept.setPid(BizCst.STU_TOP_DEPT);
                    stuDept.setVersion(0);
                    stuDept.setNum(count);
                    depts.add(stuDept);

                    count = count + 1;
                    cm.setParent_dept_id(count);

                    //处理老师部门
                    Dept parDept = new Dept();
                    parDept.setId(count);
                    parDept.setType(BizCst.PAR_TYPE);
                    parDept.setSimplename(fullclass);
                    parDept.setFullname(fullclass+"老师");
                    parDept.setPid(BizCst.PAR_TOP_DEPT);
                    parDept.setVersion(0);
                    parDept.setNum(count);
                    depts.add(parDept);

                    //处理班级
                    clss.add(cm);

                    count++;
                }
            }
            //Blade.dao().executeUpdate(new SQLReady("truncate table tb_classes"));
            Blade.dao().insertBatch(Classes.class,clss);
            Blade.dao().insertBatch(Dept.class,depts);

            //删除班级下拉缓存
            CacheKit.remove(ConstCache.SYS_CACHE,CLASS_SELECT_CACHE);
			CacheKit.remove(ConstCache.SYS_CACHE,ALL_CLASS_CACHE);


            String reson = ExcelStatistic.statistic(result.getList().size(),clss.size(),filePath);
            
            return reson;
        } catch (Exception e) {
            if (e instanceof ExcelImportException){
                throw new BizException(e.getMessage(),e);
            }
            throw new BizException("导入失败",e);
        }finally {
            IOUtils.closeQuietly(fos);
        }
    }

    @Override
    public boolean chooseHeadTeacher(int id, int teacherId) {
        if (id == 0 || teacherId ==0){
            JLogKit.debug("id异常或者teacherId异常");
            throw new BizException("没有找到对应的记录!");
        }
        Classes c = this.findById(id);
        if (null == c){
            throw new BizException("没有找到班级记录");
        }
        c.setHead_teacher(teacherId);
        c.setUtime(new Date());
        c.setVersion(Conver.toInt(c.getVersion(),0)+1);
        return this.update(c);

    }

    @Override
    public boolean chooseSubjectTeacher(int id, String teachers) {
        if (id >0 && StrKit.notBlank(teachers)){
            Set<String> set = Sets.newHashSet();
            String[] ss = teachers.split(",");
            set.addAll(Arrays.asList(ss));
            String dest = JStrKit.wrapWithDelimiter(StringUtils.join(set,','));
            Classes c = this.findById(id);
            c.setTeachers(dest);
            c.setUtime(new Date());
            c.setVersion(c.getVersion()==null?0:c.getVersion()+1);
            return this.update(c);
        }
        return false;
    }

    @Override
    public Record convert(Classes cls) {
        //将javabean转化为maps
        Record maps = Record.parse(cls);
        //使用Func.getDictName方法从缓存中获取对应字典项的中文值
        maps.set("dict_grade_id", Func.getDictName(1001, cls.getGrade_id()));
        maps.set("is_graduate", Func.getDictName(1002, cls.getIs_graduate()));
        maps.set("head_teacher_name", service.getHeadTeacherName(maps.get("head_teacher")));
        maps.set("subject_teacher_names",service.getSubjectTeacherNames(Conver.toStr(maps.get("teachers"),"")));
        int count = Db.init().queryInt("select count(1) from tb_student where class_id = #{classid}", Record.create().set("classid",map.get("id")));
        maps.put("stu_count",count);
        return maps;
    }

    @Override
    public BiMap<String,Integer> getClassesNames() {
        List<Map<String,Object>> list = selectClassNames();
        BiMap<String,Integer> bm = HashBiMap.create();
        for (Map<String,Object> m:list
             ) {
            bm.put((String)m.get("TEXT"),(Integer) m.get("ID"));
        }
        return bm;

    }

    /**
     * 转换map ，用于combo标签生成下列查询
     * @return
     */
    public List<Map<String,Object>> dropdownClassNames(){
        return selectClassNames();
    }

    /**
     * 用于select标签下拉查询
     * @return
     */
    public List<Map<String,Object>> selectClassNames(){

        List<Map<String,Object>>  list = CacheKit.get(ConstCache.SYS_CACHE, CLASS_SELECT_CACHE, new IDataLoader() {
            @Override
            public Object load() {
                return Db.init().queryListMap("SELECT t.id AS ID,CONCAT(k.NAME,t.class_name) TEXT FROM tb_classes t LEFT JOIN tfw_dict k ON t.grade_id = k.NUM WHERE t.is_graduate = 1 AND k.CODE=1001");
            }
        });

        return list;
    }
    
	@Override
	public Map<Integer, String> allClassNames() {
		Map<Integer, String> map = CacheKit.get(ConstCache.SYS_CACHE, ALL_CLASS_CACHE);
		if(null != map){
			return map;
		}
		List<Map> list = Db.init().queryListMap("SELECT t.id AS ID,(case when t.is_graduate=2 then CONCAT(t.graduate_year,'届',k.`NAME`,t.class_name) else CONCAT(k.`NAME`,t.class_name) end) as TEXT FROM tb_classes t LEFT JOIN tfw_dict k ON t.grade_id = k.NUM WHERE k.CODE=1001");

		map = Maps.newHashMap();
        for (Map<String,Object> m:list ) {
        	map.put((Integer) m.get("ID"),(String)m.get("TEXT"));
        }
        CacheKit.put(ConstCache.SYS_CACHE, ALL_CLASS_CACHE,map);
        
        return map;
	}

    @Override
    public boolean saveClass(Classes classes) {
        classes.setCtime(new Date());
        classes.setVersion(0);


        String simpleName = Func.getDictName(1001, classes.getGrade_id()) + classes.getClass_name();

        int count = 1;
        Integer max = Db.init().queryInt("select max(id) from tfw_dept", null);
        if (null != max){
            count +=max.intValue();
        }
        // 插入班级
        Dept stuDept = new Dept();
        stuDept.setId(count);
        stuDept.setSimplename(simpleName);
        stuDept.setFullname(simpleName+"学生");
        stuDept.setPid(BizCst.STU_TOP_DEPT);
        stuDept.setVersion(0);
        stuDept.setType(BizCst.STU_TYPE);
        stuDept.setNum(30);
        Blade.create(Dept.class).save(stuDept);

        //设置两个id入classes
        classes.setStu_dept_id(count);
        count ++ ;

        //插入家长
        Dept parDept = new Dept();
        parDept.setId(count);
        parDept.setSimplename(simpleName);
        parDept.setFullname(simpleName+"家长");
        parDept.setPid(BizCst.PAR_TOP_DEPT);
        parDept.setVersion(0);
        parDept.setType(BizCst.PAR_TYPE);
        parDept.setNum(30);
        Blade.create(Dept.class).save(parDept);



        classes.setParent_dept_id(count);
        classes.setIs_graduate(1);
        boolean temp = this.save(classes);
        CacheKit.remove(ConstCache.SYS_CACHE,CLASS_SELECT_CACHE);
		CacheKit.remove(ConstCache.SYS_CACHE,ALL_CLASS_CACHE);
        return temp;
    }

    @Override
    public int delWithDept(String ids){

		try {
			Blade.create(Student.class).deleteBy("class_id in (#{join(class_id)})",Record.create().set("class_id", ids.split(",")));
			Blade.create(Parent.class).deleteBy("class_id in (#{join(class_id)})",Record.create().set("class_id", ids.split(",")));
			Db.init().delete(Db.init().getSql("Dept.delete_by_class"),Record.create().set("classes_ids",ids.split(",")));
			
			CacheKit.remove(ConstCache.SYS_CACHE,CLASS_SELECT_CACHE);
			CacheKit.remove(ConstCache.SYS_CACHE,ALL_CLASS_CACHE);
			return this.deleteByIds(ids);
		} catch (Exception e) {
			throw new BizException("删除失败",e);
		} 

    }

    @Override
    public boolean newYear() {
        // 达到毕业条件，直接毕业，grade_id=3 时设置is_graduate ,graduate_year
        String year = DateKit.getYear() ;
        Date now = new Date();
        int graduate = Conver.toInt(map.get("config.graduate"),3);
        Map<String,Object> map = Maps.newHashMap();
        map.put("graduate_year",year);
        map.put("grade_id",graduate);
        map.put("now",now);

        this.updateBy("is_graduate = 2,graduate_year = #{graduate_year},utime=#{now},version=version+1"," grade_id=#{grade_id} ",map);

        map = Maps.newHashMap();
        map.put("grade_id",graduate);
        map.put("now",now);

        //清除班级下拉缓存
        CacheKit.remove(ConstCache.SYS_CACHE,CLASS_SELECT_CACHE);
		CacheKit.remove(ConstCache.SYS_CACHE,ALL_CLASS_CACHE);
        // classes表grade+ 1
        return this.updateBy(" grade_id = grade_id+1,utime=#{now},version=version+1 ","grade_id<#{grade_id} ",map);

    }




}
